home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------
- XMODEM.C
- Main Drivers
- (c) Copyright 1985 By Donald G Krantz
- All Rights Reserved
- ----------------------------------------------------------------*/
-
- #define MAIN
- #include "stdio.h"
- #include "b:xmodem.h"
-
- char *c_tx, *c_rx, *c_txstat, *c_rxstat, *c_abort;
- int _tx(), _rx(), _txstat(), _rxstat(), _abort(), _lcon();
-
- /*----------------------------------------------------------------
- main() XMODEM main driver
- ----------------------------------------------------------------*/
- VOID main( argc, argv )
- int argc;
- char *argv[];
- {
- int i;
- init();
- printf( "XMODEM 5.0 - Osborne 1/BYE-Z - D. Krantz" );
- parsopt( &argc, argv );
- if( !option_speced || (t_r_mode == 0) || (argc < 2) )
- do_usage();
- printf( "\n%s mode, batch %s", crc ? "CRC" : "Checksum",
- batch_request ? "ON" : "OFF" );
- if( t_r_mode == 'S' )
- for( i=1 ; i < argc ; i++ )
- show_size( argv[ i ] );
- else
- if( batch_request )
- make_rxspec( argc, argv );
- printf( "\n\n* * * * Send ^X to cancel * * * *" );
- printf( "\nReady to start transfer" );
- if( t_r_mode == 'R' )
- rx_exec( argc, argv );
- else
- tx_exec( argc, argv );
- }
-
- /*---------------------------------------------------------------
- error() does error abort cleanup
-
- References globals: fd;
- ---------------------------------------------------------------*/
- VOID error( str )
- char *str;
- {
- tx( CAN ); /* alert remote */
- sprintf( msg, "\n\nError - %s\n", str );
- lcl_str( msg );
- printf( msg );
- exit( 1 );
- }
-
- /*----------------------------------------------------------------
- abort() checks for carrier.
- ----------------------------------------------------------------*/
- VOID abort()
- {
- if( !ret_a( c_abort, 0,0,0,0 ) )
- exit( 1 );
- }
-
- /*----------------------------------------------------------------
- rx() gets a char from the remote system.
- ----------------------------------------------------------------*/
- char rx() { return( ret_a( c_rx,0,0,0,0 ) ); }
-
- /*----------------------------------------------------------------
- rxstat() returns TRUE if a char is awaiting input.
- ----------------------------------------------------------------*/
- rxstat() { abort(); return( ret_a( c_rxstat,0,0,0,0 ) ); }
-
- /*----------------------------------------------------------------
- tx() sends a char to remote and updates the CRC buffer.
- ----------------------------------------------------------------*/
- VOID tx( ch )
- {
- int i;
- for( i=0 ; i < 1000; i++ )
- {
- if( txstat() )
- {
- ret_a( c_tx, ch, 0,0,0 );
- updcrc( ch );
- return;
- }
- }
- error( "Transmitter timed out" );
- }
-
- /*----------------------------------------------------------------
- txstat() returns TRUE if tx register is empty.
- ----------------------------------------------------------------*/
- txstat() { abort(); return( ret_a( c_txstat, 0,0,0,0 ) ); }
-
- /*----------------------------------------------------------------
- init() moves Osborne code out into the heap where it can
- operate safely.
- ----------------------------------------------------------------*/
- init()
- {
- c_tx = alloc( 11 );
- c_rx = alloc( 11 );
- c_txstat = alloc( 11 );
- c_rxstat = alloc( 11 );
- c_abort = alloc( 15 );
- movmem( (char *)_tx, c_tx, 11 );
- movmem( (char *)_rx, c_rx, 11 );
- movmem( (char *)_txstat, c_txstat, 13 );
- movmem( (char *)_rxstat, c_rxstat, 13 );
- movmem( (char *)_abort, c_abort, 15 );
- }
-
- /*----------------------------------------------------------------
- movmem() transfers blocks of memory.
- ----------------------------------------------------------------*/
- movmem( source, dest, count )
- char *source, *dest;
- int count;
- {
- register int i;
- for( i=0 ; i<count ; i++ )
- *(dest++) = *(source++);
- }
-
- /*----------------------------------------------------------------
- lcl_char() outputs a char to the local console.
- ----------------------------------------------------------------*/
- VOID lcl_char( ch )
- char ch;
- {
- ret_a( _lcon, 0, ch, 0, 0 );
- }
-
- #if LOG_ON
- /*----------------------------------------------------------------
- log_xfr() logs uploads and downloads
- ----------------------------------------------------------------*/
- VOID log_xfr( name, mode, logfile )
- char *name, *mode;
- {
- FILE *fp;
-
- if( (fp=fopen( logfile, "r" )) == NULL )
- {
- fp = fopen( logfile, "w" );
- if( fp )
- {
- fprintf( fp, "XMODEM File Transfer Log\n" );
- fclose( fp );
- }
- }
- else
- fclose( fp );
- fp = fopen( logfile, "a" );
- fprintf( fp, "%-15s : %8s : %d/%d/%d\n",
- name, mode, month(), day(), year() );
- fclose( fp );
- }
-
- month()
- { return( *((char *)0xEF64) ); }
-
- day()
- { return( *((char *)0xEF63) ); }
-
- year()
- { return( *((char *)0xEF65) ); }
-
- #endif
- /*----------------------------------------------------------------
- rx_exec() receive mode executive driver
- ----------------------------------------------------------------*/
- rx_exec( argc, argv )
- int argc;
- char *argv[];
- {
- char fcb[ NAMESIZE + 1 ]; /* used by unparse() */
- char name[ NAMESIZE + 5]; /* unparsed name */
-
- if( batch_request )
- while( TRUE )
- {
- while( rxstat() )
- rx();
- rxname( fcb );
- unparse( name, fcb );
- sprintf( msg, "\nReceiving: %s\n", name );
- lcl_str( msg );
- rxfile( make( name ) );
- #if LOG_ON
- log_xfr( name, "UPLOAD", UPLOG );
- #endif
- }
- else
- {
- rxfile( make( argv[ 1 ] ) );
- #if LOG_ON
- log_xfr( argv[ 1 ], "UPLOAD", UPLOG );
- #endif
- }
- }
-
- /*----------------------------------------------------------------
- tx_exec() transmit mode executive driver.
- ----------------------------------------------------------------*/
- tx_exec( argc, argv )
- int argc;
- char *argv[];
- {
- int i;
- if( batch_request )
- {
- for( i=1 ; i<argc ; i++ )
- {
- fd = fopen( argv[ i ], "rb" );
- sprintf( msg, "\nSending: %s\n", argv[ i ] );
- lcl_str( msg );
- txname( parse( argv[ i ], scr_name ) );
- txfile( fd );
- #if LOG_ON
- log_xfr( argv[ i ], "DOWNLOAD", DOWNLOG );
- #endif
- }
- while(
- wait( 10, TRUE, TRUE ) != NAK )
- ;
- tx( ACK );
- sleep();
- tx( EOT );
- }
- else
- {
- fd = fopen( argv[ 1 ], "rb" );
- txfile( fd );
- #if LOG_ON
- log_xfr( argv[ 1 ], "DOWNLOAD", DOWNLOG );
- #endif
- }
- }
-
- /*----------------------------------------------------------------
- parsopt() parses the command line options and extracts all
- "dash" options from the command line argument list.
- ----------------------------------------------------------------*/
- VOID parsopt( argc, argv )
- int *argc;
- char *argv[];
- {
- int i, j;
-
- batch_request = FALSE;
- crc = TRUE;
- t_r_mode = 0;
- for( i = 1 ; i < *argc ; i++ )
- {
- if( *argv[ i ] == '-' )
- {
- option_speced = TRUE;
- switch( *(argv[ i ] + 1) )
- {
- case 'R':
- if( t_r_mode != 0 )
- {
- sprintf( msg, "Ambiguous Option: %s", argv[ i ] );
- error( msg );
- }
- t_r_mode = 'R';
- break;
- case 'S':
- if( t_r_mode != 0 )
- {
- sprintf( "Ambiguous Option: %s", argv[ i ] );
- error( msg );
- }
- t_r_mode = 'S';
- break;
- case 'B':
- batch_request = TRUE;
- break;
- case 'C':
- crc = FALSE;
- break;
- default:
- sprintf( msg, "Unrecognised option: %s", argv[ i ] );
- error( msg );
- }
- for( j = i ; j < *argc ; j++ )
- argv[ j ] = argv[ j + 1 ];
- (*argc)--;
- i--;
- }
- }
- }
-
- /*----------------------------------------------------------------
- do_usage() prints use instructions and then exits.
- ----------------------------------------------------------------*/
- VOID do_usage()
- {
- printf( "\n** This XMODEM probably doesn't work like you think **\n\n" );
- printf( "Usage is: XMODEM {option list} {filespec}\n\n" );
- printf( "Options are: -Recieve -Send -Batch -Checksum\n\n" );
- printf( "Examples: XMODEM -S ANYFILE.NAM\n" );
- printf( " XMODEM -S -B C:ANYDOC A:LU.DOC\n" );
- printf( " XMODEM -R ARTICLE.NSL\n" );
- printf( " XMODEM -R -B -C D:\n\n" );
- printf( "* \"Send\" means BeeB sends TO YOU\n" );
- printf( "* \"Receive\" means YOU send TO BeeB\n" );
- printf( "* Wildcards not allowed for \"filespec\"\n" );
- printf( "* for -R option in BATCH mode, use drivespec ONLY." );
- exit( 1 );
- }
-
- /*----------------------------------------------------------------
- show_size() prints the size (in records) of a file.
- ----------------------------------------------------------------*/
- VOID show_size( str )
- char *str;
- {
- if( index( str, '.' ) != NULL )
- if( strncmp( index( str, '.' ), ".COM" ) == 0 )
- error( "\n? Hey, what's this? I don't do .COM files!" );
- if( (fd = fopen( str, "rb" )) == NULL )
- {
- sprintf( msg,"\nAborting - can't open %s", str );
- error( msg );
- }
- printf( "\n%-14s - size = %04d records", str,
- (int)(fseek( fd, 0, 2 )/128 ));
- fclose( fd );
- }
-
- /*----------------------------------------------------------------
- make() opens a file for reception. make() changes .COM files to
- .OBJ files, and ensures that unique names are used. Returns the
- FILE pointer to the open file.
- ----------------------------------------------------------------*/
- FILE *make( name )
- char *name;
- {
- char fullname[ 20 ];
- int i;
- FILE *fp;
-
- if( strncmp( index( name, '.' ), ".COM", 4 ) == 0 )
- strcpy( index( name, '.' ), ".OBJ" );
- strcpy( fullname, rx_spec );
- strcat( fullname, name );
- for( i = 0 ; i < 10 ; i++ )
- {
- if( (fp=fopen( fullname, "r" )) == NULL )
- {
- if( (fp=fopen( fullname, "wb" )) == NULL )
- {
- sprintf( msg,"\nAborting - can't create %s",fullname);
- error( msg );
- }
- return( fp );
- }
- fullname[ strlen( fullname ) - 1 ] = i + '1';
- fclose( fp );
- }
- sprintf( msg, "\nAborting - can't open %s", fullname );
- error( msg );
- }
-
- /*----------------------------------------------------------------
- lcl_str outputs a string to the local console.
- ----------------------------------------------------------------*/
- VOID lcl_str( str )
- char *str;
- {
- while( *str != '\0' )
- {
- if( *str == '\n' )
- lcl_char( '\r' );
- lcl_char( *str );
- str++;
- }
- }
-
- VOID make_rcxspec( argc, argv )
- int argc;
- char *argv[];
- {
- if( !batch_request )
- if( argc == 2 )
- return;
- if( argc == 1 )
- {
- rx_spec[ 0 ] = '\0';
- return;
- }
- if( argc == 2 )
- if( (strlen( argv[ 1 ]) == 2) && ( *(argv[1]+1) == ':'))
- {
- strcpy( rx_spec, argv[ 1 ] );
- return;
- }
- printf( "\nAborting - improper receive filespec" );
- do_usage();
- }
-
- {
- strcpy( rx_spec, argv[ 1 ] );
- return;
- }
- printf( "\nAborting - improper receive files